#include <sem.h>
#include <i386.h>
#include <loader.h>

#if 0
extern void spin_lock(uint32 *sl);
extern void spin_unlock(uint32 *sl);
#endif

static inline void sem_begin(sem_t *s){
	(void) s;
	cli();
}

static inline void sem_end(sem_t *s){
	(void) s;
	sti();
}

static inline void sem_stopping(sem_t *s){
	(void) s;
}

void sem_init(){
}

void sem_wait(sem_t* s) {
	sem_begin(s);
	if(s->vl > 0){
		(s->vl)--;
	}
	else{
		sem_stopping(s);
		loader_enqueue((int *) &s->q);
		outb(0x20,0x20);
	}
	sem_end(s);
}

void sem_signaln(sem_t* s) {
	sem_begin(s);
	if(s->q == -1) {
		(s->vl) += (s->vl < s->vs) & 1;
	}
	else {
		loader_unqueue((int *) &s->q);
	}
	sem_end(s);
}

void sem_broadcast(sem_t* s) {
	sem_begin(s);
	while(s->q != -1){
		loader_unqueue((int *) &s->q);
	}
	sem_end(s);
}

